package com.zxb.base.monitor.vo;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zxb.base.monitor.util.LayoutUtil;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author Zxb
 */
@Data
@Builder
@Accessors(chain = true)
public class Gc {
    /**
     * GC收集器
     */
    private List<GcCollector> collectors;

    @Override
    public String toString() {
        return Optional.ofNullable(collectors).orElse(ListUtil.empty()).stream().map(Gc.GcCollector::toString).collect(Collectors.joining(StrUtil.LF));
    }

    public JSONArray toJSON() {
        JSONArray ja = new JSONArray();
        for(GcCollector collector:collectors){
            JSONObject jo = new JSONObject();
            jo.put("name", collector.getName());
            jo.put("count", collector.getCount());
            jo.put("time", DateUtil.formatBetween(collector.getTime(), BetweenFormatter.Level.MILLISECOND)
                    .replaceAll(BetweenFormatter.Level.MILLISECOND.getName(), "ms")
                    .replaceAll(BetweenFormatter.Level.SECOND.getName(), "s")
                    .replaceAll(BetweenFormatter.Level.MINUTE.getName(), "m")
                    .replaceAll(BetweenFormatter.Level.HOUR.getName(), "h")
                    .replaceAll(BetweenFormatter.Level.DAY.getName(), "d"));
            ja.add(jo);
        }
        return ja;
    }

    /**
     * GC收集器
     */
    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    public static class GcCollector {

        /**
         * 收集器名称
         */
        private String name;

        /**
         * 收集总数
         */
        private long count;

        /**
         * 收集耗时
         */
        private long time;

        @Override
        public String toString() {
            return LayoutUtil.Table.of(name,
                    LayoutUtil.Row.of("Count", count),
                    LayoutUtil.Row.of("Time", DateUtil.formatBetween(time, BetweenFormatter.Level.MILLISECOND)
                            .replaceAll(BetweenFormatter.Level.MILLISECOND.getName(), "ms")
                            .replaceAll(BetweenFormatter.Level.SECOND.getName(), "s")
                            .replaceAll(BetweenFormatter.Level.MINUTE.getName(), "m")
                            .replaceAll(BetweenFormatter.Level.HOUR.getName(), "h")
                            .replaceAll(BetweenFormatter.Level.DAY.getName(), "d"))
            ).toString();
        }

    }
}
